<template>
  <el-row style="width: 100%; height: 100vh" ref="viewerContainer" class="demo-viewer">
    <vc-viewer ref="vueCesium" :logo="false" @ready="ready">
      <vc-collection-polyline v-if="collectionPolylineData.length" :polylines="collectionPolylineData">
        <vc-polyline :positions="polylineData" :width="5" :material="{
          fabric: {
            type: 'Color',
            uniforms: {
              color: '#3071F4FF'
            }
          }
        }"></vc-polyline>
      </vc-collection-polyline>
      <vc-collection-primitive v-if="collectionPolygonsData.length" :polygons="collectionPolygonsData"></vc-collection-primitive>
    </vc-viewer>
  </el-row>
  <div class="draw-btns">
    <div class="map-draw-btn" @click="handleMapDraw">{{ drawingBtnStatus ? '退出' : '' }}地图画线</div>
    <div class="map-redraw-btn" v-if="drawingBtnStatus" @click="handleMapRedraw">重画</div>
  </div>
</template>

<script setup>
import { ref, shallowRef } from "vue";

const centerData = ref([
  {
    name: "中心点-标识",
    lng: 123.440092, //标签经度
    lat: 41.813635, //标签纬度
    value: 100,
  },
]);

const props = defineProps({
  housingSupplyStatsData: {
    type: Object,
    default: () => {},
  },
});

const vueCesium = ref(null) // cesium-domref
const drawingBtnStatus = ref(false) // 画线按钮btn

const collectionPolylineData = ref([]) // collection-polyline数据list
const polylineData = ref([]) // polyline数据list

const collectionPolygonsData = ref([]) // collection-polygon数据list

const VCCesium = shallowRef(null) // 原生cesium实例
const VCViewer = shallowRef(null) // vue-cesium-viewer实例

const polylines = props.housingSupplyStatsData;

const ready = ({ Cesium, viewer }) => {
  VCCesium.value = Cesium
  VCViewer.value = viewer
  // 去除水印
  viewer._cesiumWidget._creditContainer.style.display = "none";
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(123.440092, 41.813635, 10000),
    orientation: {
      heading: Cesium.Math.toRadians(75.0),
      pitch: Cesium.Math.toRadians(-90),
      roll: 0.0,
    },
  });
  // viewer.scene.screenSpaceCameraController.maximumZoomDistance = 100000;
  viewer.scene.screenSpaceCameraController.minimumZoomDistance = 10;
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

  //  加载离线地图
  viewer.imageryLayers.addImageryProvider(
      new Cesium.UrlTemplateImageryProvider({
        // url: "http://192.168.30.225:8088/mapsatellite/{z}/{x}/{y}.jpg",   //卫星地图
        url: 'http://192.168.30.225:8088/map/{z}/{x}/{y}.png',   //二维地图
        fileExtension: 'png',
      })
  );



  // 点击中心点
  viewer.screenSpaceEventHandler.setInputAction(function (click) {
    const pickedObject = viewer.scene.pick(click.position);
    if (pickedObject && pickedObject.id.isSxt) {
      if (pickedObject.id.cameraName == "中心点-标识") {
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(123.440092, 41.813635, 10000),
          orientation: {
            heading: Cesium.Math.toRadians(75.0),
            pitch: Cesium.Math.toRadians(-90),
            roll: 0.0,
          },
          duration: 1, // 飞行动画的持续时间，单位为秒
        });
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  addFun(Cesium, viewer);
};

const publicScreenCoordinatesToLngLat = (position, viewer) => { // 屏幕坐标转经纬度
  const ray = viewer.camera.getPickRay(position);
  const cartesian3 = viewer.scene.globe.pick(ray, viewer.scene);
  //笛卡尔坐标转经纬度
  const radians = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3);
  const lat = Cesium.Math.toDegrees(radians.latitude); //弧度转度
  const lng = Cesium.Math.toDegrees(radians.longitude);
  const alt = radians.height;
  return { lng, lat, alt }
}

const handleMapDraw = (drawType) => { // 地图画线逻辑
  drawingBtnStatus.value = drawType === 'redraw' ? true : !drawingBtnStatus.value
  let mouseDown = false // 鼠标是否按下
  if (drawingBtnStatus.value) {
    VCViewer.value.scene.screenSpaceCameraController.enableRotate = false; // 地图禁止旋转
    VCViewer.value.scene.screenSpaceCameraController.enableTranslate = false; // 地图禁止拖动
    VCViewer.value.screenSpaceEventHandler.setInputAction((movement) => { // 地图画线-鼠标按下
      // 清除之前的区域
      VCViewer.value.entities.removeAll();
      mouseDown = false;
      collectionPolylineData.value = []
      polylineData.value = []
      collectionPolygonsData.value = []
      if (!mouseDown) {
        mouseDown = true;
        const { position } = movement // 屏幕坐标
        const { lng, lat } = publicScreenCoordinatesToLngLat(position, VCViewer.value)
        collectionPolylineData.value.push({ positions: {lng, lat} })
        polylineData.value.push([lng, lat])
      }
    }, VCCesium.value.ScreenSpaceEventType.LEFT_DOWN);

    VCViewer.value.screenSpaceEventHandler.setInputAction(async (movement) => { // 地图画线-鼠标移动
      if (mouseDown) {
        const { startPosition, endPosition } = movement // 屏幕坐标
        const { lng, lat } = publicScreenCoordinatesToLngLat(startPosition, VCViewer.value)
        collectionPolylineData.value.push({ positions: {lng, lat} })
        polylineData.value.push([lng, lat])
      }
    }, VCCesium.value.ScreenSpaceEventType.MOUSE_MOVE);

    VCViewer.value.screenSpaceEventHandler.setInputAction((movement) => { // 地图画线-鼠标松开
      if (mouseDown) {
        const { position } = movement // 屏幕坐标
        const { lng, lat } = publicScreenCoordinatesToLngLat(position, VCViewer.value)
        collectionPolylineData.value.push({ positions: {lng, lat} })
        polylineData.value.push([lng, lat])

        collectionPolygonsData.value = [ // 绘制区域
          {
            positions: polylineData.value,
            appearance: {
              type: 'MaterialAppearance',
              options: {
                material: '#B8CBF147'
              }
            }
          }
        ]

        collectionPolylineData.value.push(collectionPolylineData.value[[0]]) // polyline首尾相连
        polylineData.value.push(polylineData.value[0]) // polyline首尾相连

        mouseDown = false

        VCViewer.value.scene.screenSpaceCameraController.enableRotate = true; // 恢复地图旋转功能
        VCViewer.value.scene.screenSpaceCameraController.enableTranslate = true; // 恢复地图拖动功能
        removeDrawListener();
      }
    }, VCCesium.value.ScreenSpaceEventType.LEFT_UP);
  } else {
    VCViewer.value.entities.removeAll();
    removeDrawArea();
    removeDrawListener();

    addFun(VCCesium.value, VCViewer.value)
  }
}

const handleMapRedraw = () => { // 重画按钮
  collectionPolylineData.value = []
  polylineData.value = []
  collectionPolygonsData.value = []
  handleMapDraw('redraw');
}

const removeDrawListener = () => { // 移除画线鼠标事件监听
  if (VCViewer.value) {
    VCViewer.value.screenSpaceEventHandler.removeInputAction(VCCesium.value.ScreenSpaceEventType.LEFT_DOWN);
    VCViewer.value.screenSpaceEventHandler.removeInputAction(VCCesium.value.ScreenSpaceEventType.MOUSE_MOVE);
    VCViewer.value.screenSpaceEventHandler.removeInputAction(VCCesium.value.ScreenSpaceEventType.LEFT_UP);
  }
}

const removeDrawArea = () => { // 移除画线区域
  collectionPolylineData.value = []
  polylineData.value = []
  collectionPolygonsData.value = []
}

// 动态图标
const getImageUrl = (name) => {
  return new URL(`../../assets/img/gisPage/${name}.png`, import.meta.url).href;
};

// 添加标签
const addFun = (Cesium, viewer) => {
  // 清空模型所有标签
  viewer.entities.removeAll();
  // 中心点摄像头数据
  for (let item of props.housingSupplyStatsData.concat(centerData.value)) {
    viewer.entities.add({
      isSxt: "camera",
      cameraName: item.name,
      position: Cesium.Cartesian3.fromDegrees(item.lng, item.lat, 100),
      billboard: {
        image: getImageUrl(item.name == "中心点-标识" ? "address-map" : "ggp"), // 创建一个红色圆形图标
        width: item.name == "中心点-标识" ? 50 : 200,
        height: item.name == "中心点-标识" ? 50 : 200,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        scale: 1.0,
        show: true,
        distanceDisplayCondition:
            item.name == "中心点-标识" ? new Cesium.DistanceDisplayCondition(500000, 20000000000000) : new Cesium.DistanceDisplayCondition(0, 500000), //隐藏实体标签
      },
      label: {
        text: item.name + "\n" + item.money + "元/m²" + "\n" + item.num + "个",
        font: "bold 30px sans-serif",
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.BLACK,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        show: item.name == "中心点-标识" ? false : true,
        pixelOffset: new Cesium.Cartesian2(2, 2), // 设置文字投影效果
        distanceDisplayCondition:
            item.name == "中心点-标识" ? new Cesium.DistanceDisplayCondition(500000, 20000000000000) : new Cesium.DistanceDisplayCondition(0, 500000), //隐藏实体标签
      },
    });
  }
};
</script>

<style scoped lang="less">
.draw-btns {
  position: absolute;
  left: 30px;
  top: 70px;
  display: flex;
  .map-draw-btn, .map-redraw-btn {
    cursor: pointer;
    background-color: #265c68;
    padding: 5px 10px;
    color: white;
    border-radius: 5px;
  }
  .map-redraw-btn {
    margin-left: 10px;
  }
}
</style>
